//
//  SSCommonGame.m
//  SGF
//
//  Created by shanshan on 10-6-10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "SSCommonGame.h"

#import "SSGameScene.h"
#import "SSHighScoreScene.h"
#import "SSHUD.h"

#import "SSLevelSelectScene.h"
#import "SSMenuScene.h"
#import "SimpleAudioEngine.h"
#import "SSStorage.h"

#import "WeaponEntityView.h"
#import "SSEntityView.h"

#import "GameSoundManager.h"

#import "SSGameOverLayer.h"

@interface SSCommonGame(Private)
-(void)initJoystick;
	
@end

#define MAX_Y = 160
#define MIN_Y = 85

@implementation SSCommonGame


@synthesize currentLevel, currentLevelIndex, gameScore, levelScore, livesLeft, gameFieldLayer, hud, hudLayer, centerPoint, screenSize, soundEngine;

@synthesize leftJoystick;
@synthesize rightButton;
@synthesize playerView;
@synthesize monsterProjectiles;
@synthesize escapedMonsters;
@synthesize monsterHit = _monsterHit;

#pragma mark -
#pragma mark Memory

- (void) dealloc{
	[super dealloc];
}

#pragma mark -
#pragma mark Init
//Methods
//- (id)init
//{
//	return [self initWithLevel:[[Level0001 alloc] init] atScore:0 withLivesLeft:(int)[SSStorage getDefaultLives]];
//};

-(id)initWithLevel:(SSLevel *)level haveJoystick:(BOOL)haveJoystick atScore:(int)score withLivesLeft:(int)lives{
	self = [super init];
	
	if(self != nil)
	{
		soundEngine = [GameSoundManager sharedManager].soundEngine;
		
		self.isTouchEnabled = YES;
		self.isAccelerometerEnabled = YES;
		
		CMLog(@"Game->initWithLevel");
		[self setCurrentLevel:level];//addRetain
		
		[self setGameScore:score];
		
		[self setLivesLeft:lives];
		
		//LOAD THEME		
		
		//RESET LEVEL SCORE
		[self setLevelScore:0];
		
		//LEVEL
		[self buildLevel];
		
		//HUD
		[self buildHUD];
		
		//StartLevel
		[self startLevel];	
		
		//Joystick
		if (haveJoystick) {
			[self initJoystick];
		}
		
	}	
	return self;
}

- (id)initWithLevel:(SSLevel*)level atScore:(int)score withLivesLeft:(int)lives
{
	self = [super init];
	
	if(self != nil)
	{
		[self initWithLevel:level haveJoystick:YES atScore:score withLivesLeft:lives];
	}	
	return self;
}

- (void)buildLevel
{
	CMLog(@"Game->buildLevel");
	gameFieldLayer = [[CCLayer alloc]init];
	[self addChild:gameFieldLayer];
		
	
	//Add Background
	CCSprite *bg = [currentLevel background];
	[self setScreenSize:[currentLevel getLevelSize]];
	bg.position = ccp([self screenSize].height / 2, [self screenSize].width / 2);
	
	[gameFieldLayer addChild:bg];
	
	//Addd Weather
	if ([currentLevel emitter] != nil) {
	//[currentLevel emitter].position = ccp(self.position.x + 52, self.position.y + 28);
		[currentLevel emitter].position = ccp([self screenSize].height/2, [self screenSize].width);
		[bg addChild:[currentLevel emitter] z:10];
	}
	
	//Add Items
	
	//Add Player
	[self spawnPlayer];
	//	
	//	//Add Objects	
	//	[self spawnCar];
	
	monsters = [[NSMutableArray alloc] init];
	playerProjectiles = [[NSMutableArray alloc] init];
	monsterProjectiles = [[NSMutableArray alloc] init];
	escapedMonsters = [[NSMutableArray alloc] init];
    
}

- (void) buildHUD
{
	CMLog(@"Game->buildHUD");
	hudLayer = [[CCLayer alloc]init];
	[self addChild:hudLayer];
	
	hud = [[SSHUD alloc]init];
	[hudLayer addChild:hud];
}

#pragma mark -
#pragma mark time methods

-(void)startSchedule{
	[self schedule:@selector(secondUpdate:) interval:1.0];
	
	//Main Loop
	[self schedule: @selector(tick:) interval:1.0/60];
	[self schedule: @selector(spawnEnemies:) interval:7.0f];
	
}

-(void)stopSchedule{
	[self unschedule:@selector(secondUpdate:)];
	
	//Main Loop
	[self unschedule: @selector(tick:)];
	[self unschedule: @selector(spawnEnemies:)];
	
}

- (void) startLevel
{
	CMLog(@"Game->startLevel");
	//Start background music
	soundEngine.backgroundMusicVolume = 1.0f;
	[soundEngine rewindBackgroundMusic];
	if ([SSStorage getMusic]) {
		[soundEngine playBackgroundMusic: currentLevel.bgMusic];
	}
		
	[self startSchedule];	
	//Add Enemies
	//[self spawnEnemies];
}

-(void)fire:(ccTime)dt{
	
}


-(void)checkDelete:(ccTime)dt{
	
}

- (void) tick: (ccTime)dt
{
	//CMLog(@"...Tick...");
	
	//[player updateForceVector:[hud getInputVector] withDeltaTime:dt];
	
	//[self setViewpointCenter:[playerView position]];
	
	CMLog(@"PLAYER X:%f Y:%f ROT:%f",playerView.position.x,playerView.position.y,playerView.rotation);
	[self fire:dt];
	[self checkDelete:dt];
	//[playerView updateHealth:1 maxHealth:2 position:@"right"];
	[self applyJoystick:leftJoystick toNode:playerView forTimeDelta:dt];
}

- (void)secondUpdate:(ccTime)dt {
    
}

- (void) setViewpointCenter:(CGPoint)point
{
	//NSLog(@"point x:%f y:%f",point.x, point.y);
	CGPoint localCenterPoint = ccp(240,160);
	
	viewPoint = ccpSub(localCenterPoint, point);
	//NSLog(@"viewPoint x:%f y:%f",viewPoint.x, viewPoint.y );
	
	//NSLog(@"VIEWPOINT.X: %f  Y: %f", viewPoint.x, viewPoint.y);
	
	// dont scroll so far so we see anywhere outside the visible map which would show up as black bars
	if(point.x < localCenterPoint.x)
	{
		viewPoint.x = 0;
	}
	
	if(point.y < localCenterPoint.y)
	{
		viewPoint.y = 0;
	}
	
	if(point.x > (([currentLevel getLevelSize].width) - 240))
	{
		viewPoint.x = -(([currentLevel getLevelSize].width) -480);
		//NSLog(@"VIEWPOINT.X: %f  Y: %f", viewPoint.x, viewPoint.y);
		
	}
	
	if(point.y > (([currentLevel getLevelSize].height) - 160))
	{
		viewPoint.y = -(([currentLevel getLevelSize].height) -320);
		//NSLog(@"VIEWPOINT.X: %f  Y: %f", viewPoint.x, viewPoint.y);
		
	}
	
	[gameFieldLayer setPosition:viewPoint];
	
}

#pragma mark -
#pragma mark gameOver

- (void) onGameOver
{
	//[[CCDirector sharedDirector] replaceScene:[SSLevelSelectScene node]];
	[[CCDirector sharedDirector] pause];
	//[self pauseSchedulerAndActions];
//	[gameFieldLayer pauseSchedulerAndActions];
//	[gameFieldLayer pauseSchedulerAndActions];
//	[[CCActionManager sharedManager] pauseAllActionsForTarget:gameFieldLayer];
//	[soundEngine pauseBackgroundMusic];
//	[soundEngine stopBackgroundMusic];
	//[self stopSchedule];
	
	if ([SSStorage getSound]) {
		[soundEngine playEffect:@"gameover.wav" pitch:1.0f pan:0.0f gain:1.0f];
	}
	
	gameOverLayer = [[SSGameOverLayer alloc] init];
	[gameFieldLayer addChild:gameOverLayer  z:10];
	
	
}

- (void) onLevelEnd
{
	self.gameScore += self.levelScore; 
	[SSStorage setCurrentGameScore:gameScore];
	[SSStorage setCurrentLevelIndex:self.currentLevelIndex+=1];
	[[CCDirector sharedDirector] replaceScene:[SSGameScene node]];
};

#pragma mark -
#pragma mark Joystick

-(void)initJoystick{
	CMLog(@"in initJoystick");
	
	SneakyJoystickSkinnedBase *leftJoy = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
	leftJoy.position = ccp(64,64);
	leftJoy.backgroundSprite = [ColoredCircleSprite circleWithColor:ccc4(255, 0, 0, 128) radius:64];
	leftJoy.thumbSprite = [ColoredCircleSprite circleWithColor:ccc4(0, 0, 255, 200) radius:32];
	leftJoy.joystick = [[SneakyJoystick alloc] initWithRect:CGRectMake(0,0,128,128)];
	//leftJoy.velocity = CGPointMake(0, 0.1f);
	leftJoystick = [leftJoy.joystick retain];
	leftJoy.tag = 'lJoy';
	[self addChild:leftJoy];
	
	SneakyButtonSkinnedBase *rightBut = [[[SneakyButtonSkinnedBase alloc] init] autorelease];
	rightBut.position = ccp(448,32);
	rightBut.defaultSprite = [ColoredCircleSprite circleWithColor:ccc4(255, 255, 255, 128) radius:32];
	rightBut.activatedSprite = [ColoredCircleSprite circleWithColor:ccc4(255, 255, 255, 255) radius:32];
	rightBut.pressSprite = [ColoredCircleSprite circleWithColor:ccc4(255, 0, 0, 255) radius:32];
	rightBut.button = [[SneakyButton alloc] initWithRect:CGRectMake(0, 0, 64, 64)];
	rightButton = [rightBut.button retain];
	rightButton.isToggleable = YES;
	rightBut.tag = 'rBtn';
	[self addChild:rightBut];
	
	//[[CCDirector sharedDirector] setAnimationInterval:1.0f/60.0f];
	//[self schedule:@selector(tick:) interval:1.0f/120.0f];
	
}

//function to apply a velocity to a position with delta
//static CGPoint applyVelocity(CGPoint velocity, CGPoint position, float delta){
//	float newY = position.y + velocity.y * delta * 0.3f;
//	if (newY < 85 || newY > 178 - (0,28 * [escapedMonsters count])) {
//		newY = position.y;
//		//	[laSheep ];
//	}
//	//CMLog(@"delta: %f, newY: %f", delta, newY);
//	return CGPointMake(position.x, newY);
//	//return CGPointMake(position.x + velocity.x * delta, position.y + velocity.y * delta);
//}

-(int)minY{
	int minY = 85;
	if (escapedMonsters.count > 0) {
		int tmp = 60 + 28 * [escapedMonsters count];
		if(tmp > minY){
			minY = tmp;
		}
	}
	CMLog(@"minYminY: %d", minY);
	return minY;
}

-(CGPoint) applyVelocity:(CGPoint)velocity position:(CGPoint)position delta:(float)delta{
	float newY = position.y + velocity.y * delta * 0.3f;
	
//	CMLog(@"[escapedMonsters count]: %d", [[escapedMonsters lastObject] position].y);
	int minY = [self minY];
	
	if (newY < minY || newY > 178) {
		newY = position.y;
		//	[laSheep ];
	}
	//CMLog(@"delta: %f, newY: %f", delta, newY);
	return CGPointMake(position.x, newY);	
}

-(void)updateNewPostionForPlayer{
	int minY = [self minY];

	CMLog(@"playerView.position.y: %f", playerView.position.y); 
	if (minY > playerView.position.y) {
		CGPoint newPostion = CGPointMake(playerView.position.x, minY);
		[playerView runAction:[CCMoveTo actionWithDuration:0.1f position:newPostion]];
	}
	
}

-(void)applyJoystick:(SneakyJoystick *)aJoystick toNode:(CCNode *)aNode forTimeDelta:(float)dt
{
	//CMLog(@"applyJoystick!");
	// you can create a velocity specific to the node if you wanted, just supply a different multiplier
	// which will allow you to do a parallax scrolling of sorts
	CGPoint scaledVelocity = ccpMult(aJoystick.velocity, 480.0f); 
	
	// apply the scaled velocity to the position over delta
	//aNode.position = applyVelocity(scaledVelocity, aNode.position, dt);
	aNode.position = [self applyVelocity:scaledVelocity position:aNode.position delta:dt];
}


#pragma mark -
#pragma mark spawn

- (void) spawnEnemies:(ccTime)dt{
	
}

- (void)spawnPlayer {
    
}

#pragma mark -
#pragma mark Touch Controls
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	//NSLog(@"GAME.ccTouchesBegan");
}

- (void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
	//NSLog(@"GAME.ccTouchesMoved");
}

- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	//NSLog(@"GAME.ccTouchesEnded");
}

@end
